;UNIVERSIDAD DEL VALLE DE GUATEMALA
;CONSTRUCCION DE COMPILADORES
;MARTIN GUZMAN - 08041
;PROYECTO FINAL

.MODEL	LARGE
.STACK	5000h
;-----------------------------------------
.DATA

TO_PRINT	DB	5 DUP(0), '$'	; NUMBER TO PRINT
ENTRAR	DB	0DH, 0AH, '$'

;-----------------------------------------

.CODE


;#############################################################

START	PROC	NEAR
	.STARTUP
	XOR	AX, AX
	XOR	BX, BX
	XOR	CX, CX
	XOR	DX, DX

	;--- METHOD CALL -------------------------
	PUSH	0d	;ESPACIO PARA DIRECCION DE RETORNO
	PUSH	0d	;ESPACIO PARA t1
	;ESPACIO PARA DATOS LOCALES - 1
	PUSH	0d
	;ESPACIO PARA PARAMETROS - 1
	CALL	main
	;-----------------------------------------

	MOV	AH, 4Ch
	INT	21h

START	ENDP
;#############################################################


;#############################################################

PRINT	PROC	NEAR

	;--- corregir direccion ret ----
	POP	DX
	MOV	BX, SP
	MOV	[SS:BX+2], DX
	;-------------------------------

	MOV	BX, SP
	MOV	BX, [SS:BX+0]

	MOV	DL, 10d
	MOV	CX, 5d
	MOV	DI, 4d
PRI$1:
	XOR	AX, AX
	MOV	AX, BX
	DIV	DL

	ADD	AH, 48d
	MOV	[TO_PRINT+DI], AH
	XOR	AH, AH
	MOV	BX, AX
	ADD	BX, 0d
	JZ	PRI$2
	DEC	DI
	LOOP	PRI$1
PRI$2:
	LEA	DX, [TO_PRINT+DI]

	MOV	AH, 09h
	INT	21H

	LEA	DX, [ENTRAR]

	MOV	AH, 09h
	INT	21H

;POP DEL REGISTRO DE ACTIVACION
	POP	DX
	RET
PRINT	ENDP
;#############################################################




;#############################################################
;Method: main
;	params - 0
;	Local Data - 2
;	Temporal - 2
;	Dir ret - 2
;	Val ret - void - 0
;#############################################################
main	PROC	NEAR

	;--------------------------
	POP	DX
	MOV	DI, SP
	MOV	[SS:DI+4], DX
	;--------------------------

;--- <assign> ----------------------------
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	PUSH	0	;param literal - Ackermann - 1
	PUSH	0	;param literal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+2], DX	;t$_1 <- DX
	;--- methodCall end - Ackermann ----------
	MOV	AX, [SS:DI+2]	;AX <- t$_1
	MOV	[SS:DI+0], AX	;stack[0] <- AX
;-----------------------------------------
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+2], AX	;t$_1 <- AX
	;--- MethodCall - print ------------------
	PUSH	0d	;for the return dir
	; local data space - 0
	; parameters space - 1
	MOV	DX, [SS:DI+2]	;DX <- t$_1
	PUSH	DX	;param temporal - print - 1

	CALL	print
	MOV	DI, SP	;return DI to this method
	;--- methodCall end - print --------------
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	PUSH	2	;param literal - Ackermann - 1
	PUSH	3	;param literal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+2], DX	;t$_1 <- DX
	;--- methodCall end - Ackermann ----------
	;--- MethodCall - print ------------------
	PUSH	0d	;for the return dir
	; local data space - 0
	; parameters space - 1
	MOV	DX, [SS:DI+2]	;DX <- t$_1
	PUSH	DX	;param temporal - print - 1

	CALL	print
	MOV	DI, SP	;return DI to this method
	;--- methodCall end - print --------------
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	PUSH	3	;param literal - Ackermann - 1
	PUSH	3	;param literal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+2], DX	;t$_1 <- DX
	;--- methodCall end - Ackermann ----------
	;--- MethodCall - print ------------------
	PUSH	0d	;for the return dir
	; local data space - 0
	; parameters space - 1
	MOV	DX, [SS:DI+2]	;DX <- t$_1
	PUSH	DX	;param temporal - print - 1

	CALL	print
	MOV	DI, SP	;return DI to this method
	;--- methodCall end - print --------------
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	PUSH	4	;param literal - Ackermann - 1
	PUSH	3	;param literal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+2], DX	;t$_1 <- DX
	;--- methodCall end - Ackermann ----------
	;--- MethodCall - print ------------------
	PUSH	0d	;for the return dir
	; local data space - 0
	; parameters space - 1
	MOV	DX, [SS:DI+2]	;DX <- t$_1
	PUSH	DX	;param temporal - print - 1

	CALL	print
	MOV	DI, SP	;return DI to this method
	;--- methodCall end - print --------------

	;--- METHOD END'S ---------
L_main_end:
	ADD	SP, 4d	;to POP
	RET
main	ENDP

;#############################################################




;#############################################################
;Method: Ackermann
;	params - 4
;	Local Data - 0
;	Temporal - 8
;	Dir ret - 2
;	Val ret - int - 2
;#############################################################
Ackermann	PROC	NEAR

	;--------------------------
	POP	DX
	MOV	DI, SP
	MOV	[SS:DI+12], DX
	;--------------------------

;### if(<exp>) <block1> ##################
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JE	L_Ackermann_13	;==
	JMP	L_Ackermann_14
L_Ackermann_13:
	JMP	L_Ackermann_1
L_Ackermann_14:
	MOV	AX, 0	;AX <- 0
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	JMP	L_Ackermann_2
L_Ackermann_1:
	MOV	AX, 1	;AX <- 1
	MOV	[SS:DI+4], AX	;t$_1 <- AX
L_Ackermann_2:
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JE	L_Ackermann_15	;==
	JMP	L_Ackermann_16
L_Ackermann_15:
	JMP	L_Ackermann_0
L_Ackermann_16:
	MOV	AX, [SS:DI+2]	;AX <- stack[2]
	MOV	[SS:DI+6], AX	;t$_2 <- AX
	MOV	DX, 1	;DX <- 1
	MOV	CX, [SS:DI+6]	;CX <- t$_2
	ADD	CX, DX
	MOV	[SS:DI+6], CX	;t$_2 <- CX
	MOV	DX, [SS:DI+6]	;DX <- t$_2
	MOV	[SS:DI+14], DX	;return_dir <- DX
	JMP	L_Ackermann_end
L_Ackermann_0:
;#########################################
;### if(<exp>) <block1> ##################
	;=== <boolean exp> (and) =======
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JG	L_Ackermann_17	;>
	JMP	L_Ackermann_18
L_Ackermann_17:
	JMP	L_Ackermann_4
L_Ackermann_18:
	MOV	AX, 0	;AX <- 0
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	JMP	L_Ackermann_5
L_Ackermann_4:
	MOV	AX, 1	;AX <- 1
	MOV	[SS:DI+4], AX	;t$_1 <- AX
L_Ackermann_5:
	MOV	AX, [SS:DI+2]	;AX <- stack[2]
	MOV	[SS:DI+6], AX	;t$_2 <- AX
	MOV	AX, [SS:DI+6]	;AX <- t$_2
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JE	L_Ackermann_19	;==
	JMP	L_Ackermann_20
L_Ackermann_19:
	JMP	L_Ackermann_6
L_Ackermann_20:
	MOV	AX, 0	;AX <- 0
	MOV	[SS:DI+6], AX	;t$_2 <- AX
	JMP	L_Ackermann_7
L_Ackermann_6:
	MOV	AX, 1	;AX <- 1
	MOV	[SS:DI+6], AX	;t$_2 <- AX
L_Ackermann_7:
	MOV	DX, [SS:DI+6]	;DX <- t$_2
	MOV	CX, [SS:DI+4]	;CX <- t$_1
	AND	CX, DX
	MOV	[SS:DI+4], CX	;t$_1 <- CX
	;===============================
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JE	L_Ackermann_21	;==
	JMP	L_Ackermann_22
L_Ackermann_21:
	JMP	L_Ackermann_3
L_Ackermann_22:
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	PUSH	1	;param literal - Ackermann - 1
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+8], AX	;t$_3 <- AX
	MOV	DX, 1	;DX <- 1
	MOV	CX, [SS:DI+8]	;CX <- t$_3
	SUB	CX, DX
	MOV	[SS:DI+8], CX	;t$_3 <- CX
	MOV	DX, [SS:DI+8]	;DX <- t$_3
	PUSH	DX	;param temporal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+6], DX	;t$_2 <- DX
	;--- methodCall end - Ackermann ----------
	MOV	DX, [SS:DI+6]	;DX <- t$_2
	MOV	[SS:DI+14], DX	;return_dir <- DX
	JMP	L_Ackermann_end
L_Ackermann_3:
;#########################################
;### if(<exp>) <block1> ##################
	;=== <boolean exp> (and) =======
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JG	L_Ackermann_23	;>
	JMP	L_Ackermann_24
L_Ackermann_23:
	JMP	L_Ackermann_9
L_Ackermann_24:
	MOV	AX, 0	;AX <- 0
	MOV	[SS:DI+4], AX	;t$_1 <- AX
	JMP	L_Ackermann_10
L_Ackermann_9:
	MOV	AX, 1	;AX <- 1
	MOV	[SS:DI+4], AX	;t$_1 <- AX
L_Ackermann_10:
	MOV	AX, [SS:DI+2]	;AX <- stack[2]
	MOV	[SS:DI+6], AX	;t$_2 <- AX
	MOV	AX, [SS:DI+6]	;AX <- t$_2
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JG	L_Ackermann_25	;>
	JMP	L_Ackermann_26
L_Ackermann_25:
	JMP	L_Ackermann_11
L_Ackermann_26:
	MOV	AX, 0	;AX <- 0
	MOV	[SS:DI+6], AX	;t$_2 <- AX
	JMP	L_Ackermann_12
L_Ackermann_11:
	MOV	AX, 1	;AX <- 1
	MOV	[SS:DI+6], AX	;t$_2 <- AX
L_Ackermann_12:
	MOV	DX, [SS:DI+6]	;DX <- t$_2
	MOV	CX, [SS:DI+4]	;CX <- t$_1
	AND	CX, DX
	MOV	[SS:DI+4], CX	;t$_1 <- CX
	;===============================
	MOV	AX, [SS:DI+4]	;AX <- t$_1
	MOV	CX, 0	;CX <- 0
	CMP	AX, CX
	JE	L_Ackermann_27	;==
	JMP	L_Ackermann_28
L_Ackermann_27:
	JMP	L_Ackermann_8
L_Ackermann_28:
	MOV	AX, [SS:DI+2]	;AX <- stack[2]
	MOV	[SS:DI+10], AX	;t$_4 <- AX
	MOV	DX, 1	;DX <- 1
	MOV	CX, [SS:DI+10]	;CX <- t$_4
	SUB	CX, DX
	MOV	[SS:DI+10], CX	;t$_4 <- CX
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	MOV	DX, [SS:DI+10]	;DX <- t$_4
	PUSH	DX	;param temporal - Ackermann - 1
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+10], AX	;t$_4 <- AX
	MOV	DX, [SS:DI+10]	;DX <- t$_4
	PUSH	DX	;param temporal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+8], DX	;t$_3 <- DX
	;--- methodCall end - Ackermann ----------
	;--- MethodCall - Ackermann --------------
	PUSH	0d	;for the return value
	PUSH	0d	;for the return dir
	PUSH	0d	;for t$_4
	PUSH	0d	;for t$_3
	PUSH	0d	;for t$_2
	PUSH	0d	;for t$_1
	; local data space - 0
	; parameters space - 2
	MOV	DX, [SS:DI+8]	;DX <- t$_3
	PUSH	DX	;param temporal - Ackermann - 1
	MOV	AX, [SS:DI+0]	;AX <- stack[0]
	MOV	[SS:DI+8], AX	;t$_3 <- AX
	MOV	DX, 1	;DX <- 1
	MOV	CX, [SS:DI+8]	;CX <- t$_3
	SUB	CX, DX
	MOV	[SS:DI+8], CX	;t$_3 <- CX
	MOV	DX, [SS:DI+8]	;DX <- t$_3
	PUSH	DX	;param temporal - Ackermann - 2

	CALL	Ackermann
	POP	DX	;return value
	MOV	DI, SP	;return DI to this method
	MOV	[SS:DI+6], DX	;t$_2 <- DX
	;--- methodCall end - Ackermann ----------
	MOV	DX, [SS:DI+6]	;DX <- t$_2
	MOV	[SS:DI+14], DX	;return_dir <- DX
	JMP	L_Ackermann_end
L_Ackermann_8:
;#########################################
	MOV	[SS:DI+14], WORD PTR 0	;return_dir <- 0
	JMP	L_Ackermann_end

	;--- METHOD END'S ---------
L_Ackermann_end:
	ADD	SP, 12d	;to POP
	RET
Ackermann	ENDP

;#############################################################



;-----------------------------------------
END	START
